﻿// This file is part of Code4Public (http://code4public.codeplex.com)
// Copyright 2011 Sina Iravanian - <sina@sinairv.com>
//
// This source file(s) may be redistributed, altered and customized
// by any means PROVIDING the authors name and all copyright
// notices remain intact.
// THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED. USE IT AT YOUR OWN RISK. THE AUTHOR ACCEPTS NO
// LIABILITY FOR ANY DATA DAMAGE/LOSS THAT THIS PRODUCT MAY CAUSE.
// ------------------------------------------------------------------


using System;
using System.Diagnostics;
using System.IO;
using Code4Public.Utils;
using System.Drawing;
using YAXLib;

namespace Code4Public.Settings
{
    [YAXSerializeAs("root")]
    public class AppSettings
    {
        private static readonly AppSettings s_settingsInstance = GetAppSettings(CodeConstants.Configs.AppSettingsPath);
        public static AppSettings Settings
        {
            get
            {
                return s_settingsInstance;
            }
        }

        /// <summary>
        /// Gets a reference to the collection of parsing errors.
        /// </summary>
        [YAXDontSerialize]
        public YAXParsingErrors ParsingErrors { get; private set; }

        /// <summary>
        /// Gets if there were any errors during parsing the application settings file.
        /// </summary>
        [YAXDontSerialize]
        public bool HasErrors
        {
            get
            {
                return ParsingErrors.Count > 0;
            }
        }

        public AppSettings()
        {
            LoadDefaultSettings();
        }

        public static AppSettings GetAppSettings(string path)
        {
            if (String.IsNullOrEmpty(path))
                throw new ArgumentException("path cannot be empty or null!", "path");

            if (!File.Exists(path))
                throw new FileNotFoundException("The specified file cannot be found!", path);

            var ser = new YAXSerializer(typeof(AppSettings), YAXExceptionHandlingPolicies.ThrowErrorsOnly, YAXExceptionTypes.Warning);
            var settings = (AppSettings)ser.DeserializeFromFile(path);
            Debug.Assert(settings != null);
            settings.ParsingErrors = ser.ParsingErrors;
            return settings;
        }

        private void LoadDefaultSettings()
        {
            LanguagesFilePath = CodeConstants.Configs.DefaultLanguagesPath;
            ColorProfilesPath = CodeConstants.Configs.DefaultColorProfilesPath;
            CodeConstantsPath = CodeConstants.Configs.DefaultCodeConstantsPath;
            ThemesPath = CodeConstants.Configs.DefaultThemesPath;

            ReplaceTabs = CodeConstants.Configs.DefaultReplaceTabs;
            TabSize = CodeConstants.Configs.DefaultTabSize;
            DefaultTextColor = CodeConstants.Configs.DefaultTextColor;

            DefaultThemeName = "";
            DefaultColorProfileName = "";
        }

        public void SaveToFile(string path)
        {
            var ser = new YAXSerializer(typeof(AppSettings), YAXExceptionHandlingPolicies.ThrowErrorsOnly, YAXExceptionTypes.Warning);
            ser.SerializeToFile(this, path);
        }

        [YAXAttributeFor("LanguagesFile#path")]
        public string LanguagesFilePath { get; set; }

        [YAXAttributeFor("ColorProfilesFile#path")]
        public string ColorProfilesPath { get; set; }

        [YAXAttributeFor("CodeConstantsFile#path")]
        public string CodeConstantsPath { get; set; }

        [YAXAttributeFor("ThemesFile#path")]
        public string ThemesPath { get; set; }

        [YAXAttributeFor("DefaultColorProfile#name")]
        public string DefaultColorProfileName { get; set; }

        [YAXAttributeFor("DefaultTheme#name")]
        public string DefaultThemeName { get; set; }

        [YAXAttributeFor("DefaultLanguageName#name")]
        public string DefaultLanguageName { get; set; }

        [YAXAttributeFor("TabSize#value")]
        public int TabSize { get; set; }

        [YAXAttributeFor("ReplaceTabs#value")]
        public bool ReplaceTabs { get; set; }

        [YAXCustomSerializer(typeof(ColorSerializer))]
        [YAXAttributeFor("DefaultTextColor#value")]
        public Color DefaultTextColor { get; set; }
    }
}
